import * as echarts from "echarts";
import {
  array2DoubleGroup,
  arrayKeys,
  array2ArrayMap,
} from "@/views/components/utils";
// import { GridComponent } from "echarts/components";

// echarts.use([GridComponent]);

export const EmptyChart = {
  name: "EmptyChart",
  template: `<div ref="chart" style="min-width: 400px;min-height: 300px;width:98%;"></div>`,
  data() {
    return {
      chart: null,
      updateOpts: { replaceMerge: ["series"] },
    };
  },
  mounted() {
    setTimeout(this.createChart, 300);
  },
  methods: {
    createChart() {
      if (this.chartOption === undefined || this.chartOption === null) {
        throw new Error("chartOption not defined");
      }
      const el = this.$refs["chart"];
      this.chart = echarts.init(el);
      this.chart.setOption(this.chartOption);
      this.updateChart();
    },
    updateChart() {
      if (this.chart === null) {
        return;
      }
      const option = this.createOption();
      if (null === option) {
        return;
      }
      this.chart.setOption(option, this.updateOpts);
    },
    createOption() {
      throw new Error("rewrite function createOption");
    },
  },
};

export const ValueChart = {
  name: "ValueChart",
  mixins: [EmptyChart],
  data() {
    return {
      chartType: "bar",
      list: [],
      sourceAsc: false,
      valueFormat: null,
      valueKeys: [],
      groupKeys: [],
    };
  },
  created() {
    if (this.valueFormat === null) {
      throw new Error("valueFormat can not been null");
    }
  },
};
export const GroupValueChart = {
  name: "DoubleGroupChart",
  mixins: [ValueChart],
  methods: {
    createOption() {
      const { valueFormat, valueKeys, groupKeys, list, chartType } = this;
      if (list.length == 0) {
        return null;
      }
      if (this.valueKeys === null || this.valueKeys.length !== 1) {
        throw new Error("valueKeys must have one value");
      }
      if (groupKeys.length !== 2) {
        throw new Error("groupKeys length must been 2");
      }
      const groupKey = groupKeys[0],
        xAxisKey = groupKeys[1];
      const columnKeys = arrayKeys(list, groupKey);
      const legend = {
        show: true,
        data: columnKeys,
        right: "10%",
      };
      const map = array2ArrayMap(list, groupKey, xAxisKey, valueKeys[0]);
      const series = Object.keys(map).map((key) => {
        return {
          name: key,
          type: chartType,
          data: map[key],
          // showSymbol: false,
          smooth: true,
        };
      });

      return {
        legend,
        yAxis: [
          {
            name: this.$t(valueFormat[valueKeys[0]].unit),
          },
        ],
        series,
      };
    },
  },
};

export const DoubleGroupChart = {
  name: "DoubleGroupChart",
  mixins: [ValueChart],
  methods: {
    createOption() {
      const { valueFormat, valueKeys, groupKeys, list, chartType } = this;
      if (list.length == 0) {
        return null;
      }
      if (this.valueKeys === null || this.valueKeys.length !== 1) {
        throw new Error("valueKeys must have one value");
      }
      if (groupKeys.length !== 2) {
        throw new Error("groupKeys length must been 2");
      }
      const rowKey = groupKeys[0],
        columnKey = groupKeys[1];
      const columnKeys = arrayKeys(list, columnKey);
      const legend = {
        show: true,
        data: columnKeys,
        right: "10%",
      };
      const dimensions = [rowKey, ...columnKeys];
      const source = array2DoubleGroup(list, rowKey, columnKey, valueKeys[0]);
      const series = columnKeys.map((column) => {
        return {
          name: column,
          type: chartType,
        };
      });

      return {
        legend,
        yAxis: [
          {
            name: this.$t(valueFormat[valueKeys[0]].unit),
          },
        ],
        dataset: [
          {
            dimensions,
            source: source,
          },
        ],
        series,
      };
    },
  },
};

export const MultipleValueChart = {
  name: "MultipleValueChart",
  mixins: [ValueChart],
  data() {
    const vm = this;
    return {
      seriesTooltipFormatter: function (params, ticket, callback) {
        const { valueKeys, valueFormat } = vm;
        const { seriesName, dimensionNames, seriesIndex, data, marker } =
          params;
        const html = `${data[dimensionNames[0]]}<br/>${marker}${seriesName} : ${
          data[dimensionNames[seriesIndex + 1]]
        } ${vm.$t(valueFormat[valueKeys[0]].unit)}`;
        return html;
      },
    };
  },
  created() {
    this.checkChartKeys();
  },
  methods: {
    checkChartKeys() {
      const { groupKeys, valueKeys } = this;
      if (groupKeys === null || groupKeys.length !== 1) {
        throw new Error("groupKeys must have one value");
      }
      if (valueKeys.length === 0) {
        throw new Error("valueKeys can not been []");
      }
    },
    createOption() {
      this.checkChartKeys();
      const {
        groupKeys,
        valueKeys,
        list,
        valueFormat,
        chartType,
        seriesTooltipFormatter,
      } = this;
      if (list.length == 0) {
        return null;
      }
      var legendData = [];
      const dimensions = [...groupKeys];
      const series = [];
      for (var i = 0; i < valueKeys.length; i++) {
        const key = valueKeys[i];
        dimensions.push(key);
        const serieName = this.$t(valueFormat[key].name);
        legendData.push(serieName);
        series.push({
          name: serieName,
          type: chartType,
          tooltip: {
            show: true,
            formatter: seriesTooltipFormatter,
          },
        });
      }
      return {
        legend: {
          show: true,
          data: legendData,
          right: "10%",
        },
        yAxis: {
          name: this.$t(valueFormat[valueKeys[0]].unit),
        },
        dataset: [
          {
            source: list,
            dimensions,
          },
        ],
        series,
      };
    },
  },
};

export default {
  GroupValueChart,
  MultipleValueChart,
  DoubleGroupChart,
};
